package com.atguigu.schedule.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * YOLO API统一管理服务
 * 负责管理YOLO检测的所有API调用和状态
 */
@Slf4j
@Service
public class YOLOApiManager {
    
    private static final String YOLO_API_SCRIPT = "/opt/smart-care-car/yolo_object_detection_api.py";
    private static final String YOLO_MODEL_PATH = "/opt/smart-care-car/yolo二维目标检测/yolov5s.pt";
    private static final String TEMP_DIR = "/tmp/yolo_detection";
    
    private final ExecutorService executorService = Executors.newFixedThreadPool(2);
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    // YOLO服务状态
    private volatile boolean serviceEnabled = true;
    private volatile boolean modelLoaded = false;
    private volatile Map<String, Object> modelInfo = new HashMap<>();
    private volatile List<Map<String, Object>> lastDetectionResults = new ArrayList<>();
    private volatile long lastDetectionTime = 0;
    
    /**
     * 初始化YOLO API管理器
     */
    public void initialize() {
        log.info("🚀 初始化YOLO API管理器...");
        
        // 创建临时目录
        try {
            Files.createDirectories(Paths.get(TEMP_DIR));
        } catch (IOException e) {
            log.error("创建临时目录失败", e);
        }
        
        // 加载模型信息
        loadModelInfo();
        
        log.info("✅ YOLO API管理器初始化完成");
    }
    
    /**
     * 获取模型信息
     */
    public Map<String, Object> getModelInfo() {
        if (!modelLoaded) {
            loadModelInfo();
        }
        return new HashMap<>(modelInfo);
    }
    
    /**
     * 检测图像中的目标
     */
    public CompletableFuture<List<Map<String, Object>>> detectObjects(byte[] imageData) {
        return CompletableFuture.supplyAsync(() -> {
            if (!serviceEnabled || !modelLoaded) {
                log.warn("YOLO服务未启用或模型未加载");
                return new ArrayList<>();
            }
            
            try {
                // 保存临时图像文件
                String tempImagePath = saveTempImage(imageData);
                
                // 执行YOLO检测
                List<Map<String, Object>> results = executeDetection(tempImagePath);
                
                // 更新状态
                lastDetectionResults = results;
                lastDetectionTime = System.currentTimeMillis();
                
                // 清理临时文件
                Files.deleteIfExists(Paths.get(tempImagePath));
                
                log.info("🎯 YOLO检测完成，检测到 {} 个目标", results.size());
                return results;
                
            } catch (Exception e) {
                log.error("YOLO检测失败", e);
                return new ArrayList<>();
            }
        }, executorService);
    }
    
    /**
     * 切换服务状态
     */
    public boolean toggleService(boolean enabled) {
        this.serviceEnabled = enabled;
        log.info("🔄 YOLO服务状态切换为: {}", enabled ? "启用" : "禁用");
        return serviceEnabled;
    }
    
    /**
     * 获取检测统计信息
     */
    public Map<String, Object> getDetectionStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("serviceEnabled", serviceEnabled);
        stats.put("modelLoaded", modelLoaded);
        stats.put("detectedObjects", lastDetectionResults.size());
        stats.put("lastDetectionTime", lastDetectionTime);
        stats.put("modelPath", YOLO_MODEL_PATH);
        return stats;
    }
    
    /**
     * 获取服务状态
     */
    public Map<String, Object> getServiceStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("enabled", serviceEnabled);
        status.put("modelLoaded", modelLoaded);
        status.put("modelPath", YOLO_MODEL_PATH);
        status.put("lastDetectionTime", lastDetectionTime);
        status.put("detectionCount", lastDetectionResults.size());
        return status;
    }
    
    /**
     * 加载模型信息
     */
    private void loadModelInfo() {
        try {
            ProcessBuilder pb = new ProcessBuilder(
                "python3", YOLO_API_SCRIPT, "info"
            );
            
            Process process = pb.start();
            
            StringBuilder output = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line);
                }
            }
            
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                String jsonStr = output.toString();
                
                // 查找JSON开始位置（跳过警告信息）
                int jsonStart = jsonStr.indexOf("{");
                if (jsonStart >= 0) {
                    jsonStr = jsonStr.substring(jsonStart);
                }
                
                try {
                    modelInfo = objectMapper.readValue(jsonStr, Map.class);
                    modelLoaded = true;
                    log.info("✅ YOLO模型信息加载成功");
                } catch (Exception jsonException) {
                    // 如果JSON解析失败，返回默认信息
                    modelInfo = createDefaultModelInfo();
                    modelLoaded = true;
                    log.warn("⚠️ JSON解析失败，使用默认模型信息");
                }
            } else {
                modelInfo = createDefaultModelInfo();
                modelLoaded = false;
                log.error("❌ YOLO模型信息获取失败");
            }
            
        } catch (Exception e) {
            log.error("获取YOLO模型信息失败", e);
            modelInfo = createDefaultModelInfo();
            modelLoaded = false;
        }
    }
    
    /**
     * 执行YOLO检测
     */
    private List<Map<String, Object>> executeDetection(String imagePath) {
        List<Map<String, Object>> results = new ArrayList<>();
        
        try {
            ProcessBuilder pb = new ProcessBuilder(
                "python3", YOLO_API_SCRIPT, "detect", imagePath
            );
            
            Process process = pb.start();
            
            StringBuilder output = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    output.append(line);
                }
            }
            
            int exitCode = process.waitFor();
            
            if (exitCode == 0) {
                String outputStr = output.toString();
                log.info("Python脚本输出: [{}]", outputStr);
                
                // 解析检测结果
                if (outputStr.contains("NO_OBJECTS")) {
                    log.info("未检测到目标");
                } else {
                // 解析OBJECT格式的输出
                // 查找所有OBJECT:开头的部分
                int startIndex = 0;
                while (true) {
                    int objectIndex = outputStr.indexOf("OBJECT:", startIndex);
                    if (objectIndex == -1) break;
                    
                    // 找到OBJECT:后面的内容
                    String objectStr = outputStr.substring(objectIndex + 7);
                    
                    // 找到下一个OBJECT:或字符串结尾
                    int nextObjectIndex = objectStr.indexOf("OBJECT:");
                    if (nextObjectIndex != -1) {
                        objectStr = objectStr.substring(0, nextObjectIndex);
                    }
                    
                    // 解析OBJECT数据
                    String[] parts = objectStr.split(",");
                    if (parts.length >= 6) {
                        try {
                            Map<String, Object> result = new HashMap<>();
                            result.put("type", "object");
                            result.put("x", Integer.parseInt(parts[0].trim()));
                            result.put("y", Integer.parseInt(parts[1].trim()));
                            result.put("width", Integer.parseInt(parts[2].trim()));
                            result.put("height", Integer.parseInt(parts[3].trim()));
                            result.put("class", parts[4].trim());
                            result.put("confidence", Double.parseDouble(parts[5].trim()) / 100.0); // 转换为0-1范围
                            results.add(result);
                            log.info("解析到目标: {}", result);
                        } catch (Exception e) {
                            log.warn("解析目标数据失败: {}", objectStr, e);
                        }
                    }
                    
                    startIndex = objectIndex + 7;
                }
                    log.info("解析到 {} 个检测结果", results.size());
                }
            } else {
                log.error("YOLO检测失败，退出码: {}", exitCode);
            }
            
        } catch (Exception e) {
            log.error("YOLO检测执行失败", e);
        }
        
        return results;
    }
    
    /**
     * 保存临时图像文件
     */
    private String saveTempImage(byte[] imageData) throws IOException {
        String fileName = "yolo_detection_" + System.currentTimeMillis() + ".jpg";
        Path tempPath = Paths.get(TEMP_DIR, fileName);
        Files.write(tempPath, imageData);
        return tempPath.toString();
    }
    
    /**
     * 创建默认模型信息
     */
    private Map<String, Object> createDefaultModelInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("model_loaded", true);
        info.put("model_path", YOLO_MODEL_PATH);
        info.put("device", "cpu");
        info.put("conf_threshold", 0.25);
        info.put("iou_threshold", 0.45);
        info.put("class_count", 80);
        info.put("class_names", Arrays.asList(
            "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat",
            "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat",
            "dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe", "backpack",
            "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard", "sports ball",
            "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket",
            "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
            "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake",
            "chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop",
            "mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink",
            "refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"
        ));
        return info;
    }
    
    /**
     * 清理资源
     */
    public void cleanup() {
        log.info("🧹 清理YOLO API管理器资源...");
        executorService.shutdown();
        
        // 清理临时文件
        try {
            Files.walk(Paths.get(TEMP_DIR))
                .filter(Files::isRegularFile)
                .forEach(path -> {
                    try {
                        Files.delete(path);
                    } catch (IOException e) {
                        log.warn("删除临时文件失败: {}", path, e);
                    }
                });
        } catch (IOException e) {
            log.warn("清理临时文件失败", e);
        }
        
        log.info("✅ YOLO API管理器资源清理完成");
    }
}
